#include "sys.h"
#include "log.h"
#include "net.h"
#include "ghttp.h"
#include "cJSON.h"

cJSON* http_post(char* url, char* data)
{
    cJSON* resp = NULL;
    int ret = 0;
    ghttp_request* req = NULL;

    log_trace("url:%s", url);
    log_trace("data:%s", data);

    req = ghttp_request_new();
    if (!req) {
        log_error("ghttp req new error.");
        return NULL;
    }
    if (ghttp_set_uri(req, url) == -1) {
        log_error("http set uri error:%s", ghttp_get_error(req));
        goto out;
    }
    if (ghttp_set_type(req, ghttp_type_post) == -1) {
        log_error("http set type error:%s", ghttp_get_error(req));
        goto out;
    }
    ghttp_set_header(req, "Content-Type", "application/json");
    ghttp_set_body(req, data, strlen(data));
    ghttp_prepare(req);
    ghttp_process(req);
    resp = cJSON_Parse(ghttp_get_body(req));
    log_trace("resp:%s", ghttp_get_body(req));
out:
    ghttp_request_destroy(req);
    return resp;
}

int http_download_get_url(char* url, char* data, char* down_url, char* version)
{
    int ret = 0;
    cJSON *resp, *json;
    ghttp_request* req;

    log_trace("url:%s", url);
    log_trace("post data:%s", data);
    req = ghttp_request_new();
    if (!req) {
        log_error("ghttp req new error.");
        goto out;
    }
    if (ghttp_set_uri(req, url) == -1) {
        log_error("http set uri error:%s", ghttp_get_error(req));
        goto out;
    }
    if (ghttp_set_type(req, ghttp_type_post) == -1) {
        log_error("http set type error:%s", ghttp_get_error(req));
        goto out;
    }
    // ghttp_set_header(req, "Content-Type", "application/json");
    ghttp_set_body(req, data, strlen(data));
    ghttp_prepare(req);
    if (ghttp_error == ghttp_process(req)) {
        log_error("http request download url failed.");
        goto out;
    }
    resp = cJSON_Parse(ghttp_get_body(req));
    log_trace("resp:%s", ghttp_get_body(req));

    if (!cJSON_IsObject(resp)) {
        log_error("HTTP download url resp is not json data.");
        goto out;
    }
    json = cJSON_GetObjectItem(resp, "status");
    if (json) {
        if (strcmp(json->valuestring, "1") != 0) {
            json = cJSON_GetObjectItem(resp, "code");
            log_warn("Get %s failed code:%s.", url, json->valuestring);
            json = cJSON_GetObjectItem(resp, "msg");
            log_warn("Get %s failed msg:%s.", url, json->valuestring);
            goto out;
        }
    }

    json = cJSON_GetObjectItem(resp, "version");
    strcpy(version, json->valuestring);

    json = cJSON_GetObjectItem(resp, "url");
    strcpy(down_url, json->valuestring);
    ret = 1;
out:
    if (req)
        ghttp_request_destroy(req);
    if (resp)
        cJSON_Delete(resp);
    return ret;
}
int http_download_file(char* url, char* out_file)
{
    int ret = 0, len;
    char* content;
    cJSON *resp, *json;
    ghttp_request* req = NULL;
    FILE* fp;

    log_trace("url:%s", url);
    unlink(out_file);
    req = ghttp_request_new();
    if (!req) {
        log_error("ghttp req new error.");
        goto out;
    }
    if (ghttp_set_uri(req, url) == -1) {
        log_error("http set uri error:%s", ghttp_get_error(req));
        goto out;
    }
    if (ghttp_set_type(req, ghttp_type_get) == -1) {
        log_error("http set type error:%s", ghttp_get_error(req));
        goto out;
    }
    ghttp_prepare(req);
    if (ghttp_error == ghttp_process(req)) {
        log_error("Http download %s failed.", url);
        goto out;
    }
    content = ghttp_get_body(req);
    len = ghttp_get_body_len(req);
    log_trace("http download file len:%d", len);

    fp = fopen(out_file, "wb");
    if (!fp) {
        log_syserr("HTTP download create %s failed.", out_file);
        goto out;
    }
    fwrite(content, len, 1, fp);
    fclose(fp);
    ret = 1;
out:
    if (req)
        ghttp_request_destroy(req);
    return ret;
}
void http_url(char* sch, char* host, uint16_t port, char* path, char* out)
{
    sprintf(out, "%s://%s:%u/%s", sch, host, port, path);
}



//udp
cJSON* udp_post(struct sockaddr_in *addr, char* data, int len)
{
    int fd;
    int ret;
    char buffer[1024] = {0};
    cJSON *root;

    fd = socket_dgram_new();
    sock_rcvtmo(fd, 2, 0);
    if(0 > connect(fd, (struct sockaddr*)addr, sizeof(struct sockaddr_in))){
        log_syserr("udp post connect error.");
        return NULL;
    }
    log_trace("udp post:%s", data);

    ret = write(fd, data, len);
    if(ret < 0){
        log_syserr("udp post write error.");
        close(fd);
        return NULL;
    }

    ret = read(fd, buffer, sizeof(buffer));
    if(ret < 0){
        log_syserr("udp post read error");
        close(fd);
        return NULL;
    }
    log_trace("auth response:%s", buffer);

    root = cJSON_Parse(buffer);
    if(!root){
        log_error("Response data is not json.");
        close(fd);
        return NULL;
    }

    close(fd);
    return root;
}